package com.drcoffee.drcoffeemall.service.impl;

import com.drcoffee.drcoffeemall.entry.*;
import com.drcoffee.drcoffeemall.mapper.AfterSaleMapper;
import com.drcoffee.drcoffeemall.mapper.OrderMapper;
import com.drcoffee.drcoffeemall.service.AfterSaleService;
import com.drcoffee.drcoffeemall.util.SendWxWorlUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public class AfterSaleServiceImpl implements AfterSaleService {

    final
    AfterSaleMapper afterSaleMapper;
    final
    OrderMapper orderMapper;
    private final Redisson redisson;   // 注入Redisson对象


    final
    RedisTemplate<String, Object> redisTemplate;

    final
    SendWxWorlUtil sendWxWorlUtil;

    public AfterSaleServiceImpl(AfterSaleMapper afterSaleMapper, OrderMapper orderMapper, Redisson redisson, RedisTemplate<String, Object> redisTemplate, SendWxWorlUtil sendWxWorlUtil) {
        this.afterSaleMapper = afterSaleMapper;
        this.orderMapper = orderMapper;
        this.redisson = redisson;
        this.redisTemplate = redisTemplate;
        this.sendWxWorlUtil = sendWxWorlUtil;
    }
    @Override
    public Result addAfterSale(String Token, AfterSale afterSale) {
        RLock lock = redisson.getLock("afterSale");
        try {
            lock.lock();// 加锁
            User user = (User) redisTemplate.opsForValue().get(Token);
            afterSale.setUser_account(user.getAccount());
            // 查询配件小计
            List<BigDecimal> partsTotalList = orderMapper.getOrderAttachmentsByOrder(afterSale.getOrder_code(), afterSale.getPartCodes());

            // 使用Stream API计算总和
            BigDecimal totalSum = partsTotalList.stream()
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            afterSale.setRefund_amount(totalSum);
            String code = afterSaleCode(afterSale.getType());
            afterSale.setCode(code);
            // 存储afterSale
            afterSaleMapper.addAfterSale(afterSale);
            // 存储售后记录和配件关系映射
            afterSaleMapper.addAfterAfterOrderPartM(afterSale.getCode(), afterSale.getPartCodes());
            // 发送提醒至企业微信
            sendWxWorlUtil.sendAppoint(3);
            return new Result(1, "", "", null);
        } catch (Exception e) {
            log.error("===================== addAfterSale()异常： =====================", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new Result(-1, "ERROR", e.getMessage(), null);
        } finally {
            lock.unlock();//解锁
        }
    }

    @Override
    public ResponseEntity<Object> getAfterSaleList(String Token, Map<String, Object> paramMap) {
//            String type = (String) asSearch.get("type");
//            String status = (String) asSearch.get("status");
        String search = "%" + paramMap.get("search") + "%";
        paramMap.put("search", search);
        User user = (User) redisTemplate.opsForValue().get(Token);
        paramMap.put("account", user.getAccount());

//            String typeSql = "";
//            String statusSql = "";
//            if (!Objects.equals(type, "0")) {
//                typeSql = "AND type = " + type;
//            }
//            if (status.equals("4") && type.equals("1")) {
//                statusSql = "AND status in ('4','5')";
//            } else if (status.equals("8")) {
//                statusSql = "AND status_two <> 0 ";
//            } else if (!Objects.equals(status, "0")) {
//                statusSql = "AND status = " + status;
//            }

        Integer currPage = (Integer) paramMap.get("currPage");
        Integer pageSize = (Integer) paramMap.get("pageSize");
        PageHelper.startPage(currPage, pageSize);

        List<Map<String, Object>> afterSaleList = afterSaleMapper.getAfterSaleList(paramMap);
        for (Map<String, Object> afterSaleMap : afterSaleList) {
            List<OrderAttachment> parts = afterSaleMapper.getAfterParts(afterSaleMap.get("code").toString(), afterSaleMap.get("order_code").toString());
            afterSaleMap.put("part_list", parts);
        }

        String path = afterSaleMapper.getAfterBeforePath();
        afterSaleList.forEach(afterSale -> {
            for (char c = 'a'; c <= 'e'; c++) {
                String img_key = "img_" + c;
                String propertyValue = (String) afterSale.get(img_key);
                if (!Objects.equals("", propertyValue)) {
                    afterSale.put(img_key, path + propertyValue);
                }
            }
        });
        PageInfo<Map<String, Object>> afterSalePageInfo = new PageInfo<>(afterSaleList);
        return new ResponseEntity<>(afterSalePageInfo, HttpStatus.OK);
    }

    @Override
    public Result getNotYetAfterSaleParts(String order_code) {
        try {
            // 查询订单
            Order order = orderMapper.getOrderAndPart(order_code, "CN");
      /*      if (order.getStatus() != 4) {
                // 订单没有确认收货
                return new Result(-2, "WARN", "The order has not been confirmed", null);
            }*/
            List<OrderAttachment> orderAttachmentList = order.getOrderAttachmentsList();
            // 查询售后表中存在的配件
            List<String> partCodes = afterSaleMapper.getNotYetAfterSaleParts(order_code);

            List<OrderAttachment> noAfterParts = new ArrayList<>();
            for (OrderAttachment orderAttachment : order.getOrderAttachmentsList()) {
                if (partCodes.contains(orderAttachment.getPart_code())) {
                    noAfterParts.add(orderAttachment);
                }
            }

            // 根据条件删除元素
            orderAttachmentList.removeIf(orderAttachment -> partCodes.contains(orderAttachment.getPart_code()));

            // 支付方式
            Integer payVoucherNum = afterSaleMapper.getPayVoucherCount(order_code);
            Integer payType;
            AfterSale bankInfo = null;
            if (payVoucherNum == 0) {
                payType = orderMapper.getPayType(order_code);
            } else {
                payType = 3;
                bankInfo = afterSaleMapper.getLastBankInfo(order.getUser_account());
            }
            order.setOrderAttachmentsList(orderAttachmentList);
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("order", order);
            resultMap.put("noParts", noAfterParts);
            resultMap.put("payType", payType);
            resultMap.put("bankInfo", bankInfo);
            return new Result(1, "SUCCESS", "", resultMap);
        } catch (Exception e) {
            log.error("===================== getNotYetAfterSaleParts()异常： =====================", e);
            return new Result(-1, "ERROR", e.getMessage(), null);
        }

    }

    @Override
    public Result setTransportByCode(String code, String transporCode, Integer type) {
        try {
            if (type == 1) { // 表示为添加快递单号而不是修改
                // 发送提醒至企业微信
                sendWxWorlUtil.sendAppoint(4);
            }
            afterSaleMapper.setTransportByCode(code, transporCode);
            return new Result(1, "SUCCESS", "", null);
        } catch (Exception e) {
            return new Result(-1, "ERROR", "", null);
        }
    }

    @Override
    public Result getAfterSaleByCode(String code) {
        try {
            AfterSale afterSale = afterSaleMapper.getAfterSaleByCode(code);
            List<OrderAttachment> parts = afterSaleMapper.getAfterParts(afterSale.getCode(), afterSale.getOrder_code());
            afterSale.setOrderAttachmentList(parts);

            String path = afterSaleMapper.getAfterBeforePath();
            for (char c = 'a'; c <= 'e'; c++) {
                String getterName = "getImg_" + c;
                String setterName = "setImg_" + c;
                try {
                    // 使用反射获取属性值
                    String propertyValue = (String) AfterSale.class.getMethod(getterName).invoke(afterSale);
                    if (!Objects.equals("", propertyValue)) {
                        // 使用反射设置属性值
                        AfterSale.class.getMethod(setterName, String.class).invoke(afterSale, path + propertyValue);
                    }
                } catch (Exception e) {
                    log.error("===================== AfterSale.class.getMethod()异常： =====================", e);
                }
            }
            return new Result(1, "SUCCESS", "", afterSale);
        } catch (Exception e) {
            log.error("===================== getAfterSaleByCode()异常： =====================", e);
            return new Result(-1, "ERROR", "", null);
        }
    }

    @Override
    public Result cancelAfterSale(String code) {
        try {
            afterSaleMapper.cancelAfterSale(code);
            return new Result(1, "SUCCESS", "", null);
        } catch (Exception e) {
            return new Result(-1, "ERROR", e.getMessage(), null);
        }
    }

    @Override
    public Result reissueReceiveGoods(String code) {
        try {
            afterSaleMapper.reissueReceiveGoods(code);
            return new Result(1, "SUCCESS", "", null);
        } catch (Exception e) {
            log.error("===================== reissueReceiveGoods()异常： =====================", e);
            return new Result(-1, "ERROR", e.getMessage(), null);
        }
    }

    // 生成编号
    private String afterSaleCode(Integer type) {
        RAtomicLong atomicLong = redisson.getAtomicLong("AfterSaleCode");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String PREFIX = "";
        if (type == 1) {
            PREFIX = "CT";
        } else if (type == 2) {
            PREFIX = "CH";
        } else if (type == 3) {
            PREFIX = "CK";
        }
        String currentDate = sdf.format(new Date());
        String prefix_code = PREFIX + currentDate;
        long counter = atomicLong.incrementAndGet();
        String counterFormatted = String.format("%03d", counter + 1);
        prefix_code += counterFormatted;
        return prefix_code;
    }
}
